#include <jni.h>
#include <string>
#include <map>
#include <sstream>
#include <thread>
#include <mutex>
#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <wait.h>
#include <inttypes.h>
#include <arpa/inet.h>
#include <zlib.h>
#include <sched.h>
#include <pwd.h>
#include <spawn.h>
#include <resolv.h>
#include <tar.h>
#include <getopt.h>
#include <android/log.h>
#include <android/input.h>
#include <android/imagedecoder.h>
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#include <linux/spi/spidev.h>
#include <linux/ip.h>
#include <sys/poll.h>
#include <sys/reboot.h>
#include <stdatomic.h>
#include <sys/inotify.h>
#include <sys/eventfd.h>
#include <sys/random.h>
#include <sys/timerfd.h>
#include <sys/system_properties.h>
#include <linux/string.h>
#include <linux/tcp.h>
#include <sys/socket.h>
// for native asset manager
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <limits.h>
#include <sys/limits.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <iostream>
#include <fstream>
#include <string>
#include <netdb.h>

#include <algorithm>
#include <array>
#include <limits>
#include <memory>
#include <string>
#include <vector>
#include <dirent.h>
#include <fcntl.h>
#include <grp.h>
#include <cinttypes>
#include <pwd.h>
#include <csignal>
#include <sys/epoll.h>
#include <sys/errno.h>
#include <sys/pidfd.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/sysinfo.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <sys/time.h>

#include <fcntl.h>



#include <boost/algorithm/string.hpp>
#include <boost/atomic.hpp>
#include <boost/timer/timer.hpp>

#include <nlohmann/json.hpp>
#include <curl/curl.h>

#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <event2/listener.h>
#include <event2/util.h>
#include <event2/event.h>


#define LOG_TAG "NativeLib"  // 定义日志标签


#define LOG_TAG "NDK_THREAD_DEMO"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

std::string add(std::string &&a, std::string &&b) {
    return a + b;
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_abc_robot01_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string a("1233");
    return env->NewStringUTF(a.c_str());
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_abc_robot01_MainActivity_bind(
        JNIEnv *env,
        jobject /* this */) {
    auto f1 = [] { return add("你好", "大冲商务D"); };
    return env->NewStringUTF(f1().c_str());
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_abc_robot01_MainActivity_getOptionalValue(JNIEnv *env, jobject) {
    std::optional<std::string> optValue;
    if (optValue) {
        return env->NewStringUTF(optValue->c_str());
    } else {
        return env->NewStringUTF("No Value");
    }
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_abc_robot01_MainActivity_getValueFromMap(JNIEnv *env, jobject) {
    // 创建一个 std::map 存储学生的年龄
    std::map<std::string, int> studentAgeMap = {
            {"Alice",   20},
            {"Bob",     22},
            {"Charlie", 19}
    };
    auto value = studentAgeMap["Bob"];
    return env->NewStringUTF(std::to_string(value).c_str());
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_abc_robot01_MainActivity_vector01(JNIEnv *env, jobject) {
// Create a vector containing integers
    std::vector<int> v = {8, 4, 5, 9};
// Add two more integers to vector
    v.push_back(6);
    v.push_back(9);
    return env->NewStringUTF(std::to_string(v.at(0)).c_str());
}

std::once_flag flag1;

inline void hi(int i) {
    __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "Simple example: called once");  // 打印信息日志
}

void simple_do_once() {
    std::call_once(flag1, hi, 100);
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_abc_robot01_MainActivity_ostringstream01(JNIEnv *env, jobject) {
    __android_log_print(ANDROID_LOG_INFO, LOG_TAG,
                        "Java_com_abc_robot01_MainActivity_ostringstream01");  // 打印信息日志
    std::ostringstream oss;
    // 使用 ostringstream 格式化字符串
    oss << "The formatted number is: " << 123;
    simple_do_once();
    return env->NewStringUTF(oss.str().c_str());
}

extern "C" JNIEXPORT void JNICALL
Java_com_abc_robot01_MainActivity_callJavaMethod(JNIEnv *env, jobject instance) {
    // 获取 MainActivity 类
//        jclass clazz = env->FindClass("com/abc/robot01/MainActivity");
    jclass clazz = env->GetObjectClass(instance);
    if (clazz == nullptr) {
        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Failed to find class");
        return;
    }

    // 获取要调用的方法 ID
    jmethodID methodId = env->GetMethodID(clazz, "javaMethodToCall", "()V");
    if (methodId == nullptr) {
        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Failed to find method");
        return;
    }
    // 调用 Java 方法
    env->CallVoidMethod(instance, methodId);
}


void longRunningTask() {
    // 输出开始日志
    LOGI("Long running task started.");

    // 模拟耗时任务，延迟 3 秒
    std::this_thread::sleep_for(std::chrono::seconds(3));

    // 输出任务完成日志
    LOGI("Long running task completed.");
}

extern "C" JNIEXPORT void JNICALL
Java_com_abc_robot01_MainActivity_thread01(JNIEnv *env, jobject instance) {
    // 创建并启动一个线程来执行耗时任务
    std::thread taskThread(longRunningTask);

    // 分离线程，使其在后台执行
    taskThread.detach();

    // 主线程返回
    LOGI("Native thread started and detached.");
}

// 管道文件描述符
int pipefd[2];

// 写入线程函数
void writerThread() {
    const char *message = "Hello from writer thread!";
    LOGI("Writer thread: Writing to pipe...");

    // 向管道写入数据
    write(pipefd[1], message, strlen(message));

    LOGI("Writer thread: Message written to pipe.");
}

// 读取数据函数
void readFromPipe() {
    char buffer[128];
    ssize_t bytesRead;

    LOGI("Main thread: Reading from pipe...");

    // 从管道读取数据
    bytesRead = read(pipefd[0], buffer, sizeof(buffer) - 1);

    if (bytesRead >= 0) {
        buffer[bytesRead] = '\0'; // 添加字符串终止符
        LOGI("Main thread: Read from pipe: %s", buffer);
    } else {
        LOGI("Main thread: Failed to read from pipe");
    }
}


extern "C"
JNIEXPORT void JNICALL
Java_com_abc_robot01_MainActivity_usePipe(JNIEnv *env, jobject /* this */) {
    // 创建管道
    if (pipe(pipefd) == -1) {
        LOGI("Failed to create pipe.");
        return;
    }

    // 启动写入线程
    std::thread writer(writerThread);

    // 主线程读取管道数据
    readFromPipe();

    // 等待写入线程完成
    writer.join();

    // 关闭管道
    close(pipefd[0]);
    close(pipefd[1]);
}

extern "C"
JNIEXPORT void JNICALL
Java_com_abc_robot01_MainActivity_writeFile(JNIEnv *env, jobject /* this */) {
    char text[64];
    strcpy(text, "你好中国");
    int fd = open("/sdcard/1.txt", O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644);
    write(fd, text, strlen(text));
    close(fd);
    LOGI("writeFile");
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_abc_robot01_MainActivity_writeFile2(JNIEnv *env, jobject /* this */) {
    char buffer[100];
    int id = 123;
    char name[] = "NDK";
// 使用 sprintf 格式化数据
    sprintf(buffer, "ID: %d, Name: %s\n", id, name);
    int fd = open("/sdcard/1.txt", O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644);
    write(fd, buffer, strlen(buffer));
    close(fd);
    return env->NewStringUTF(buffer);
}

extern "C" JNIEXPORT void JNICALL
Java_com_abc_robot01_MainActivity_read(JNIEnv *env, jobject /* this */) {
    std::ifstream file("/sdcard/1.txt");  // 打开文件
    if (!file.is_open()) {
        std::cerr << "无法打开文件" << std::endl;
        return;
    }
    std::string line;
    while (std::getline(file, line)) {  // 逐行读取
        LOGI("%s", line.c_str());  // 输出文件内容到日志
    }
    file.close();  // 关闭文件
    std::string result(100, 'a');
    LOGI("%s", result.c_str());

}

extern "C" JNIEXPORT jlong JNICALL
Java_com_abc_robot01_MainActivity_read2(JNIEnv *env, jobject /* this */) {
    jlong sum = 145;
    std::vector<int> numbers = {1, 2, 3, 4, 5};

    // 使用 std::for_each 打印所有元素
    std::for_each(numbers.begin(), numbers.end(), [](int n) {
        LOGI("%d", n);
    });
    return sum;
}


extern "C" JNIEXPORT void JNICALL
Java_com_abc_robot01_MainActivity_SetLongField(JNIEnv *env, jobject obj /* this */) {
// 1. Get the class reference
    jclass myClass = env->GetObjectClass(obj);

    // 2. Get the Field ID of the long field (myLongField)
    jfieldID myLongFieldID = env->GetFieldID(myClass, "num", "J");  // "J" represents the long type in JNI

    if (myLongFieldID == nullptr) {
        std::cerr << "Field ID not found!" << std::endl;
        return;
    }

    // 3. Set a new value for the long field (e.g., setting it to 100)
    jlong newValue = 100;
    env->SetLongField(obj, myLongFieldID, newValue);
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_abc_robot01_MainActivity_gettimeofday(JNIEnv *env, jobject /* this */) {
    time_t now = time(nullptr);
    struct tm *timeinfo = localtime(&now);

    char buffer[100];
    // Format the date as "YYYY-MM-DD"
    strftime(buffer, sizeof(buffer), "%Y-%m-%d", timeinfo);
    LOGI("Today's Date: %s", buffer);
    // Return the result as a Java string
    return env->NewStringUTF(buffer);

//    struct timeval tv;
//    gettimeofday(&tv, NULL);
//    // Calculate seconds and microseconds
//    long seconds = tv.tv_sec;
//    long microseconds = tv.tv_usec;
//    // Format the output string
//    char buffer[100];
//    sprintf(buffer, "Seconds: %ld, Microseconds: %ld", seconds, microseconds);
//    LOGI("Current Time: %s", buffer);
//    return env->NewStringUTF(buffer);
}

extern "C" JNIEXPORT jboolean JNICALL
Java_com_abc_robot01_MainActivity_hello(JNIEnv *env, jobject /* this */) {
    LOGI("hello");
    return JNI_TRUE ;
}

extern "C" JNIEXPORT jint JNICALL
Java_com_abc_robot01_MainActivity_hello1(JNIEnv *env, jobject /* this */) {
    jint a = 123;
    LOGI("hello1");
    return a  ;
}

/**
 *  一些常见的 Android 系统属性包括：

    ro.product.model: 设备型号。
    ro.product.brand: 设备品牌。
    ro.build.version.release: Android 版本。
    ro.product.manufacturer: 制造商。
    ro.serialno: 设备序列号。
    ro.hardware: 硬件平台。
    ro.build.id: 构建 ID。
    ro.build.display.id: 显示的构建 ID。

这些属性可以通过 __system_property_get 函数获取。
 *
 *
 */
extern "C" JNIEXPORT jstring JNICALL
Java_com_abc_robot01_MainActivity_hello3(JNIEnv *env, jobject /* this */) {
    char value[256];
    if (__system_property_get("ro.build.version.release", value) > 0) {
        printf("Android Model: %s\n", value);
    } else {
        printf("Failed to get property.\n");
    }
    LOGI("hello3");
    return env->NewStringUTF(value);
}

static atomic_int counter = ATOMIC_VAR_INIT(0);

extern "C" JNIEXPORT jstring JNICALL
Java_com_abc_robot01_MainActivity_hello4(JNIEnv *env, jobject /* this */) {
    const size_t bufferSize = 16;
    char buffer[bufferSize];

// Generate random bytes
    ssize_t result = getrandom(buffer, bufferSize, 0);
    if (result == -1) {
        perror("getrandom");
    }
    LOGI("hello4");

    // Create a string to hold the random bytes in hexadecimal format
    std::string randomString;
    for (size_t i = 0; i < bufferSize; ++i) {
        randomString += (i == 0 ? "" : " ") + std::to_string(static_cast<int>(buffer[i]));
    }
    atomic_fetch_add(&counter, 1);
    LOGI("Counter value: %d", atomic_load(&counter));
    int16_t b = 145;
    LOGI("My integer: %d", b);


    const char *host = "www.baidu.com";
    auto he = gethostbyname(host);
    if (he == nullptr) {
        LOGI("Failed to resolve hostname: %s", host);
        return env->NewStringUTF("Resolution failed");
    }
    char *ip = inet_ntoa(*(struct in_addr *)he->h_addr_list[0]);
    LOGI("Resolved IP: %s", ip);
    return env->NewStringUTF(ip);
}


#define EVENT_SIZE  ( sizeof(struct inotify_event) )
#define EVENT_BUF_LEN     ( 1024 * ( EVENT_SIZE + NAME_MAX + 1 ) )

extern "C" JNIEXPORT jint JNICALL
Java_com_abc_robot01_MainActivity_inotify01(JNIEnv *env, jobject /* this */) {
    // Initialize inotify
    int fd = inotify_init();
    if (fd < 0) {
        perror("inotify_init");
        return 1;
    }
    // Add a watch on the specified directory
    const char* watchDir = "/path/to/your/directory";
    int wd = inotify_add_watch(fd, watchDir, IN_MODIFY | IN_CREATE | IN_DELETE);
    if (wd == -1) {
        perror("inotify_add_watch");
        return 1;
    }

    char buffer[EVENT_BUF_LEN];
    while (true) {
        // Read the events
        int length = read(fd, buffer, EVENT_BUF_LEN);
        if (length < 0) {
            perror("read");
            return 1;
        }

        // Process the events
        for (int i = 0; i < length; ) {
            auto event = (struct inotify_event *) &buffer[i];
            if (event->mask & IN_CREATE) {
                std::cout << "File created: " << event->name << std::endl;
            } else if (event->mask & IN_DELETE) {
                std::cout << "File deleted: " << event->name << std::endl;
            } else if (event->mask & IN_MODIFY) {
                std::cout << "File modified: " << event->name << std::endl;
            }
            i += EVENT_SIZE + event->len; // Move to the next event
        }
    }

    // Cleanup
    inotify_rm_watch(fd, wd);
    close(fd);
    LOGI("inotify01");
    return 0  ;
}



boost::atomic<int> counter2(0); // 定义一个原子整数

void increment() {
    for (int i = 0; i < 1000; ++i) {
        ++counter2; // 原子递增
    }
}


using json = nlohmann::json;

extern "C" JNIEXPORT jstring JNICALL
Java_com_abc_robot01_MainActivity_hello5(JNIEnv *env, jobject /* this */) {
    LOGI("hello5");
    std::string example = "Boost Library Example";
    boost::to_upper(example);  // 将字符串转换为大写

   {
       std::string str = "   Hello World   ";
    boost::algorithm::trim(str);
    LOGI("trim  %s",str.c_str());
   }

    {
       std::string str = "   Hello World   ";
    boost::algorithm::trim_right(str);
    LOGI("trim  %s",str.c_str());
   }


{
   std::vector<std::string> parts = {"Boost", "Library", "Example"};
std::string joined = boost::algorithm::join(parts, " ");
 LOGI("join trim  %s",joined.c_str());
}

    {
        std::string s = "Boost,Library,Example";
        std::vector<std::string> result;
        boost::algorithm::split(result, s, boost::algorithm::is_any_of(","));

        for(const std::string& str : result) {
            std::cout << str << std::endl;
            LOGI("split: %s",str.c_str());
        }

    }
    {
        std::thread t1(increment);
        std::thread t2(increment);

        t1.join();
        t2.join();
        LOGI("Final counter value:: %d",counter2.load());
    }

    {
        // Creating JSON data
        json person = {
                {"name", "John Doe"},
                {"age", 25},
                {"is_student", true},
                {"languages", {"C++", "Java", "Kotlin"}}
        };

        // Accessing values
        std::string name = person["name"];
        int age = person["age"];
        LOGI("age; %d",age);
    }

    {
        json j;
        j["name"] = "John";
        j["age"] = 25;
        LOGI("json; %s", j.dump(4).c_str());
    }

    {
        std::string jsonStr = R"({"name":"Hank","age":32})";
        nlohmann::json j = nlohmann::json::parse(jsonStr);
        LOGI("Deserialized Name: %s", j["name"].get<std::string>().c_str());
    }

    std::string str2 = "boost boost boost";
    boost::algorithm::replace_all(str2, "boost", "Boost");
    LOGI("%s",str2.c_str());

    return env->NewStringUTF(example.c_str());
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_abc_robot01_MainActivity_png01(JNIEnv *env, jobject /* this */) {
    jint a = 123;
    LOGI("png01");
    return env->NewStringUTF("122");
}

// 回调函数，用于处理响应数据
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {
    ((std::string*)userp)->append((char*)contents, size * nmemb);
    return size * nmemb;
}

void postRequest(const char* sn_value) {
    // 初始化CURL
    CURL* curl;
    CURLcode res;

    // 存储服务器的响应数据
    std::string response_string;
    std::string header_string;

    curl_global_init(CURL_GLOBAL_DEFAULT);
    curl = curl_easy_init();

    if(curl) {
        // 设置要访问的URL
        curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.1.77:8499/robot/login");

        // 构建POST数据
        std::string post_data = "sn=" + std::string(sn_value);

        // 设置POST请求
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data.c_str());

        // 设置回调函数，用于处理服务器的响应
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_string);

        // 执行请求
        res = curl_easy_perform(curl);

        // 清理CURL
        curl_easy_cleanup(curl);

        // 检查请求是否成功
        if(res != CURLE_OK) {
            LOGI("curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
        } else {
            // 打印服务器的响应
            LOGI("Server Response: %s\n", response_string.c_str());
        }
    }
    curl_global_cleanup();
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_abc_robot01_MainActivity_png02(JNIEnv *env, jobject /* this */) {
    postRequest("123345");
    jint a = 123;
    LOGI("png01");
    return env->NewStringUTF("122");
}


extern "C" JNIEXPORT jstring JNICALL
Java_com_abc_robot01_MainActivity_timer01(JNIEnv *env, jobject /* this */) {

    boost::timer::cpu_timer timer;

    // 模拟耗时操作
    std::this_thread::sleep_for(std::chrono::seconds(1));

    // 获取并打印经过的时间
    std::cout << "Elapsed time: " << timer.format() << std::endl;
    LOGI("timer01");
    return env->NewStringUTF(timer.format().c_str());
}


// 定时器回调函数
void timer_callback(evutil_socket_t fd, short events, void *user_data) {
    LOGI("Timer triggered!");
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_abc_robot01_MainActivity_libevent01(JNIEnv *env, jobject /* this */) {
// 创建事件基础
    struct event_base *base = event_base_new();
    if (!base) {
        return env->NewStringUTF("Could not initialize libevent!");
    }

    // 创建定时器事件
    struct event *timer_event = evtimer_new(base, timer_callback, nullptr);
    struct timeval five_seconds = {2, 0}; // 5秒后触发
    evtimer_add(timer_event, &five_seconds);

    LOGI("Starting event loop. Timer will trigger in 5 seconds...");
    event_base_dispatch(base); // 启动事件循环

    // 模拟耗时操作
//    std::this_thread::sleep_for(std::chrono::seconds(3));

    // 清理
    event_free(timer_event);
    event_base_free(base);

    LOGI("timer01");
    return env->NewStringUTF("libevent01");
}

// 信号处理函数
void signal_handler(evutil_socket_t sig, short events, void *user_data) {
    LOGI("Caught signal %d", sig);
    event_base *base = (event_base *)user_data;
    event_base_loopbreak(base); // 退出事件循环
}



// FIFO 文件名
const char *fifo_path = "/data/local/tmp/event.fifo";

// 读取 FIFO 的回调函数
static void fifo_read(evutil_socket_t fd, short event, void *arg) {
    char buf[255];
    int len = read(fd, buf, sizeof(buf) - 1);
    if (len > 0) {
        buf[len] = '\0'; // 结束字符串
        LOGI("Read from FIFO: %s", buf);
    } else if (len == 0) {
        LOGI("FIFO closed.");
    } else {
        perror("Read error");
    }
}

// 向 FIFO 写入数据的线程
void write_to_fifo() {
    int fd = open(fifo_path, O_WRONLY);
    if (fd == -1) {
        LOGI("Failed to open FIFO for writing");
        return;
    }

    const char *message = "Hello from NDK!";
    for (int i = 0; i < 3; ++i) {
        write(fd, message, strlen(message));
        write(fd, "\n", 1); // 添加换行符
        std::this_thread::sleep_for(std::chrono::seconds(1)); // 每秒写一次
    }

    close(fd);
}





extern "C" JNIEXPORT jstring JNICALL
Java_com_abc_robot01_MainActivity_libevent02(JNIEnv *env, jobject /* this */) {
// 创建 FIFO
    mkfifo(fifo_path, 0666);

    // 初始化 libevent
    struct event_base *base = event_base_new();
    if (!base) {
        return env->NewStringUTF("Could not initialize libevent!");
    }

    // 打开 FIFO 以进行读取
    int fifo_fd = open(fifo_path, O_RDONLY | O_NONBLOCK);
    if (fifo_fd == -1) {
        event_base_free(base);
        return env->NewStringUTF("Could not open FIFO for reading!");
    }

    // 创建 FIFO 事件
    struct event *evfifo = event_new(base, fifo_fd, EV_READ | EV_PERSIST, fifo_read, NULL);
    if (!evfifo || event_add(evfifo, NULL) < 0) {
        close(fifo_fd);
        event_base_free(base);
        return env->NewStringUTF("Could not create or add FIFO event!");
    }

    // 启动写线程
    std::thread writer(write_to_fifo);

    // 启动事件循环
    event_base_dispatch(base);

    // 清理
    writer.join();
    event_free(evfifo);
    close(fifo_fd);
    event_base_free(base);
    unlink(fifo_path); // 删除 FIFO
    return env->NewStringUTF("Event loop finished!");
}



